<script setup lang="ts">
import {
  NForm,
  NFormItem,
  NInput,
  NButton,
  NSelect,
  useDialog,
  useMessage,
  NTreeSelect,
  NDatePicker,
  NInputNumber,
  NScrollbar,
  NTag,
  NModal,
  type SelectOption,
  type FormItemRule,
  type FormInst,
  type UploadFileInfo
} from 'naive-ui'
import { onUnmounted, onDeactivated, ref, reactive, onMounted, computed } from 'vue'
import { useRoute } from 'vue-router'
import useRouteReplace from '@/hooks/useRouteReplace'
import FixedAction from '@/components/FixedAction.vue'
import type { DicTreeModel } from '@/api/dic'
import { sendRequest } from '@/utils/api'
import type { HttpResponse } from '@/utils/http'
// import VUploader from '@/components/VUploaderV3/VUploader.vue'
// import type { CustomFile } from '@/components/VUploaderV3/types'
import VScope from '@/views/OA/Common/Scope.vue'
import FUploader from './components/FUploader.vue'

interface FormData {
  clueId: number
  name: string
  solicitMethod: string
  solicitMethodCode: string
  receiveTime: string
  transferor: string
  transferorPhone: string | null
  receiver: string
  solicitNum: number
  startTime: string
  endTime: string
  depositPeriod: string
  remark: string | null
  batchReceivers: any[]
}

const message = useMessage()
const route = useRoute()
const routeReplace = useRouteReplace(route.query.redirect as string)
const dialog = useDialog()

const formInst = ref<FormInst | null>(null)
const formData = reactive({
  batchReceivers: []
} as unknown as FormData)

const contactsModalVisible = ref(false)
const handleContactsModalSubmit = (v: any[]) => {
  formData.batchReceivers = v
  contactsModalVisible.value = false
  formData.receiver = v.map((e) => e.typeName).join(',')
}
const handleDeleteContact = (index: number) => {
  formData.batchReceivers.splice(index, 1)
  formData.receiver = formData.batchReceivers.map((e) => e.typeName).join(',')
}

// 征集方式是否为寄存代管(A3007)
const isJCDG = computed(() => formData.solicitMethodCode === 'A3007')

const clueSelectOptions = ref<SelectOption[]>([])
const clueSelectLoading = ref(false)
const queryClueSelectOptions = async () => {
  clueSelectLoading.value = true
  try {
    const [error, res] = await sendRequest<HttpResponse<DicTreeModel[]>>({
      module: 'batchV2',
      api: 'clueList'
    })

    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)
    clueSelectOptions.value = res.data
  } catch (error) {
    console.error(error)
  } finally {
    clueSelectLoading.value = false
  }
}

// 选择的线索详情
const collectorName = ref<string | null>(null)
const transferSelectOptions = ref([] as any)
const handleUpdateClueId = (id: number) => {
  // @ts-ignore
  formData.transferor = null
  formData.transferorPhone = null
  collectorName.value = null
  transferSelectOptions.value = []
  formData.clueId = id
  queryClueInfo(String(id))
}
interface ClueModel {
  collectorId: string
  concatUser: string
  concatUserPhone: string
}
const clueInfo = ref<ClueModel | null>(null)
const queryClueInfo = async (id: string) => {
  try {
    const [error, res] = await sendRequest<HttpResponse<ClueModel>>({
      module: 'clue',
      api: 'infoManage',
      uri: {
        id
      }
    })

    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)
    clueInfo.value = res.data
    formData.transferor = res.data.concatUser
    formData.transferorPhone = res.data.concatUserPhone

    sendRequest({
      module: 'collector',
      api: 'info',
      uri: {
        id: res.data.collectorId
      }
    })
      .then(([_, res]) => {
        if (res) {
          collectorName.value = res.data.userName
          transferSelectOptions.value = res.data.transferList || []
        }
      })
      .catch(() => {
        collectorName.value = null
        transferSelectOptions.value = []
      })
  } catch (error) {
    console.error(error)
  }
}

const clueMethodOptions = reactive<DicTreeModel[]>([])
const clueMethodLoading = ref(false)
const queryClueMethodOptions = async () => {
  clueMethodLoading.value = true
  try {
    const [error, res] = await sendRequest<HttpResponse<DicTreeModel[]>>({
      module: 'dic',
      api: 'getTree',
      override: {
        params: {
          dicCode: 'A30'
        }
      }
    })

    if (error) throw error
    if (res.code !== 0) throw new Error(res.msg)
    clueMethodOptions.length = 0
    clueMethodOptions.push(...(res.data[0] ? res.data[0].children || [] : []))
  } catch (error) {
    console.error(error)
  } finally {
    clueMethodLoading.value = false
  }
}
const isTrue = ref(false)
const changeTree = (v: string, o: DicTreeModel) => {
  formData.solicitMethodCode = v
  formData.solicitMethod = o.name
  if (formData.solicitMethodCode === 'A3007') {
    isTrue.value = true
  } else {
    isTrue.value = false
  }
}

const fileList = ref<UploadFileInfo[]>([])
const submitLoading = ref(false)
const handleSubmit = () => {
  formInst.value?.validate(async (error) => {
    if (error) return
    submitLoading.value = true

    try {
      const [error, res] = await sendRequest<HttpResponse>({
        module: 'batchV2',
        api: 'save',
        override: {
          data: {
            ...formData,
            // @ts-ignore
            fileIds: fileList.value ? fileList.value.map((e) => e.file?.remoteId).join(',') : null
          }
        }
      })
      if (error) throw error
      if (res.code !== 0) throw new Error(res.msg)
      message.success(res.msg)
      window.flags.flushBatch = true
      routeReplace()
    } catch (error) {
      if (!(error instanceof Error)) return
      message.error(error.message)
    } finally {
      submitLoading.value = false
    }
  })
}

const createLimitRule = (len: number): FormItemRule => {
  return {
    trigger: ['blur', 'input'],
    message: `不能超过${len}字`,
    validator: (_, value) => (value ? value.length <= len : true)
  }
}

const disablePreviousDate = (ts: number) => {
  if (!formData.startTime) return false
  return ts < new Date(formData.startTime).getTime()
}
const disableNextDate = (ts: number) => {
  if (!formData.endTime) return false
  return ts > new Date(formData.endTime).getTime()
}

onMounted(() => {
  queryClueMethodOptions()
  queryClueSelectOptions()
})
onUnmounted(() => dialog.destroyAll())
onDeactivated(() => dialog.destroyAll())
</script>

<template>
  <div class="add-batch">
    <NForm
      ref="formInst"
      :model="formData"
      :disabled="submitLoading"
      label-placement="left"
      require-mark-placement="left"
      label-width="100rem"
      class="ab-card"
    >
      <NFormItem
        label="关联线索："
        path="clueId"
        :rule="{
          required: true,
          message: '关联线索为必填项，请选择',
          trigger: ['change', 'blur']
        }"
      >
        <NSelect
          :value="formData.clueId"
          @update:value="handleUpdateClueId"
          :options="clueSelectOptions"
          :loading="clueSelectLoading"
          placeholder="请选择"
          filterable
        />
      </NFormItem>
      <NFormItem
        label="批次名称："
        path="name"
        :rule="[
          { required: true, message: '批次名称为必填项，请输入', trigger: ['blur', 'input'] },
          createLimitRule(200)
        ]"
      >
        <NInput
          v-model:value="formData.name"
          placeholder="藏家-征集方式-版本类型-征集数量"
        />
      </NFormItem>
      <NFormItem
        label="征集方式："
        path="solicitMethodCode"
        :rule="{ required: true, message: '征集方式为必填项，请选择', trigger: ['change', 'blur'] }"
      >
        <NTreeSelect
          v-model:value="formData.solicitMethodCode"
          :options="clueMethodOptions"
          :loading="clueMethodLoading"
          placeholder="请选择征集方式"
          key-field="code"
          label-field="name"
          @update-value="changeTree"
        />
      </NFormItem>
      <NFormItem
        label="接收时间："
        path="receiveTime"
        :rule="{ required: true, message: '接收时间为必填项，请选择', trigger: ['change', 'blur'] }"
      >
        <NDatePicker
          v-model:formatted-value="formData.receiveTime"
          type="datetime"
          placeholder="请选择"
        />
      </NFormItem>

      <NFormItem
        label="接收人："
        path="receiver"
        :rule="[{ required: true, message: '接收人为必填项，请输入', trigger: ['input', 'blur'] }]"
      >
        <div class="contacts">
          <NButton
            type="primary"
            ghost
            @click="contactsModalVisible = true"
          >
            选择接收人
          </NButton>
          <NScrollbar style="max-height: 210rem">
            <div
              v-show="formData.batchReceivers?.length"
              class="contacts-content"
            >
              <NTag
                v-for="(contact, index) in formData.batchReceivers"
                @close="handleDeleteContact(index)"
                :key="index"
                :color="{ color: '#ffffff' }"
                closable
                style="justify-content: space-between; gap: 0 10rem"
              >
                {{ contact.typeName }}
              </NTag>
            </div>
          </NScrollbar>
        </div>
      </NFormItem>
      <NFormItem
        label="征集数量："
        path="solicitNum"
        :rule="{
          required: true,
          message: '征集数量为必填项，请输入',
          type: 'number',
          trigger: ['blur', 'input']
        }"
      >
        <NInputNumber
          v-model:value="formData.solicitNum"
          placeholder="请输入"
          :show-button="false"
          :min="0"
          :max="Number.MAX_SAFE_INTEGER"
        />
      </NFormItem>

      <template v-if="isJCDG">
        <NFormItem
          label="开始时间："
          path="startTime"
          :rule="{
            required: true,
            message: '开始时间为必填项，请选择',
            trigger: ['change', 'blur']
          }"
        >
          <NDatePicker
            v-model:formatted-value="formData.startTime"
            type="date"
            placeholder="请选择"
            :is-date-disabled="disableNextDate"
            :actions="null"
            input-readonly
          />
        </NFormItem>
        <NFormItem
          label="结束时间："
          path="endTime"
          :rule="{
            required: true,
            message: '结束时间为必填项，请选择',
            trigger: ['change', 'blur']
          }"
        >
          <NDatePicker
            v-model:formatted-value="formData.endTime"
            type="date"
            placeholder="请选择"
            :is-date-disabled="disablePreviousDate"
            :actions="null"
            input-readonly
          />
        </NFormItem>
        <NFormItem
          label="代存期限："
          path="depositPeriod"
          :rule="[
            { required: true, message: '代存期限为必填项，请输入', trigger: ['input', 'blur'] },
            createLimitRule(20)
          ]"
        >
          <NInput
            v-model:value="formData.depositPeriod"
            placeholder="请输入"
          />
        </NFormItem>
      </template>

      <template v-if="collectorName">
        <NFormItem
          label="藏家："
          style="grid-column: 1 / 2"
        >
          <NInput
            v-model:value="collectorName"
            placeholder="/"
            disabled
          />
        </NFormItem>
        <NFormItem label="移交人：">
          <NSelect
            :value="formData.transferor"
            @update:value="
              (e, o: any) => ((formData.transferor = e), (formData.transferorPhone = o.transferPhone))
            "
            :options="transferSelectOptions"
            value-field="transferName"
            label-field="transferName"
            placehoder="请选择移交人"
            style="flex-shrink: 2; max-width: 70%"
          />
          <NInput
            v-model:value="formData.transferorPhone"
            placeholder="/"
            disabled
          />
        </NFormItem>
      </template>
      <NFormItem
        label="备注："
        path="remark"
        :rule="createLimitRule(200)"
        class="n-form-item--textarea"
      >
        <NInput
          v-model:value="formData.remark"
          type="textarea"
          placeholder="请输入"
          rows="2"
        />
      </NFormItem>

      <NFormItem
        label="附件："
        :show-feedback="false"
      >
        <FUploader v-model:file-list="fileList" />
      </NFormItem>
    </NForm>
  </div>

  <NModal
    :auto-focus="false"
    v-model:show="contactsModalVisible"
    @close="contactsModalVisible = false"
  >
    <VScope
      @close="contactsModalVisible = false"
      @scopeSubmit="handleContactsModalSubmit"
      :default-list="formData.batchReceivers!"
      flat
    />
  </NModal>

  <FixedAction>
    <div class="add-batch-buttons">
      <NButton
        color="#999999"
        ghost
        :disabled="submitLoading"
        @click="routeReplace"
        style="width: 78px; height: 34px"
      >
        取消
      </NButton>

      <NButton
        color="#5FB17F"
        :disabled="submitLoading"
        :loading="submitLoading"
        @click="handleSubmit"
        style="width: 78px; height: 34px"
      >
        保存
      </NButton>
    </div>
  </FixedAction>
</template>

<style scoped lang="scss">
.add-batch {
  min-height: 100%;
  padding: 15rem 0 110rem;
  background-color: #f0efee;

  .ab-card {
    padding: 20rem;
    background-color: #e1e1e1;
  }

  .n-form {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 6rem 30rem;
  }

  .n-form-item--textarea {
    grid-column: 1 / -1;
  }

  .n-date-picker,
  .n-input-number {
    flex: 1;
  }
}

.add-batch-buttons {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0 16rem;

  .n-button {
    width: 100rem;
    height: 50rem;
  }
}

.contacts {
  display: flex;
  flex-direction: column;
  gap: 10rem 0;

  .n-button {
    max-width: 126rem;
  }

  .contacts-content {
    display: grid;
    grid-template-columns: repeat(5, auto);
    gap: 10rem;
    padding: 15rem;
    background-color: #fff;
  }
}
</style>
